/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cmp.player.abilities;

import com.cmp.arena.Arena;
import com.cmp.core.Main;
import static com.cmp.core.constants.InputUIDConstants.ABILITY_BUTTON_UID;
import static com.cmp.core.constants.InputUIDConstants.CURSOR_POS_UID;
import static com.cmp.core.constants.UIDConstants.BALL_UID;
import com.cmp.core.utilities.PhysicsUtility;
import com.cmp.player.BulletFactory;
import com.cmp.player.controls.BulletControl;
import com.cmp.player.controls.CharacterRigidBodyControl;
import com.cmp.player.controls.CursorSelectionControl;
import com.cmp.player.controls.MoveControl;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;

/**
 * Ability of the Supporter role.
 * @author krummer
 */
public class PullControl extends AbilityControl {
    private static final float PULL_SPEED = 10.f;
    private boolean isAbility;
    private Node bullet;
    private CharacterRigidBodyControl body;
    
    @Override
    public void setSpatial(Spatial spatial) {
        super.setSpatial(spatial);
        super.setCooldown(3.f);
        super.setCastDuration(1.f);
        this.bullet = null;
        
        spatial.setUserData(ABILITY_BUTTON_UID, false);
        this.body = spatial.getControl(CharacterRigidBodyControl.class);
    }
    
    @Override
    public void execute() {
        //only do it without the ball
        Node ball = (Node) ((Node)this.spatial).getChild(BALL_UID);
                
        if((ball == null && !(this.isOnCooldown())) && body.isOnGround()) {
      
            super.activateCooldown();
            super.activateGCD();
            
            //stop moving before casting.
            this.body.setLinearVelocity(Vector3f.ZERO);
            super.activateCastTime();
            
            //create a bullet.
            this.bullet = new Node();
            this.bullet.setLocalTranslation(this.getSpatial().getLocalTranslation());
            this.bullet.move(Vector3f.UNIT_Y.mult(3.f));
            BulletFactory.makeBullet(this.bullet);
            
            BulletControl bControl = this.bullet.getControl(BulletControl.class);
            Vector3f target = getSpatial().getUserData(CURSOR_POS_UID);
            bControl.setBulletTarget(target);
            bControl.setLifeTime(this.getCastDuration());
            Main.app.getStateManager().getState(Arena.class).addBullet(this.bullet);
        }
    }
    
    private void pull(Node enemy) {
        Vector3f targetPos = enemy.getWorldTranslation().clone();
        Vector3f myPos = getSpatial().getWorldTranslation().clone();
        
        // throw enemy toward you
        Vector3f throwArch = PhysicsUtility
            .calculateVerticalLaunchSpeed(body.getGravity().y, PULL_SPEED, targetPos, myPos);
             enemy.getControl(CharacterRigidBodyControl.class)
            .setLinearVelocity(throwArch);
                    
        //lock enemies movement for duration of cast.
        enemy.getControl(MoveControl.class)
             .setRooted(true, this.getCastDuration());
                    
        enemy.getControl(CursorSelectionControl.class)
             .setRooted(true, this.getCastDuration());
        
        //destroy the bullet.
        this.bullet.getControl(BulletControl.class).remove();
        this.bullet = null;
    }

    @Override
    protected void controlUpdate(float tpf) {
        super.controlUpdate(tpf);
        
        isAbility = super.getSpatial().getUserData(ABILITY_BUTTON_UID);
        if(isAbility) {
            execute();
        }
        
        if(this.bullet != null) {
            BulletControl bulletControl = bullet.getControl(BulletControl.class);
            if(bulletControl.getCollisionNode() != null) {
                //take the first player you can get.
                if(bulletControl.getCollisionNode().getUserData("isPlayer") != null) {
                    if(!bulletControl.getCollisionNode().equals(this.getSpatial())) {
                        this.pull(bulletControl.getCollisionNode());
                    }
                }
            }
        }
    }

    @Override
    protected void controlRender(RenderManager rm, ViewPort vp) {
    }

    public Control cloneForSpatial(Spatial spatial) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
